﻿/*****************************************************************************
 * Hyldahl.Services.TaskProcessing.Test            Created by: MSH 2008.07.22
 * --------------------------------------------------------------------------
 * FileName: Data\TaskSqlDataProviderTest.cs
 * --------------------------------------------------------------------------
 * Copyright 2009 Martin Sixhøj Hyldahl
 *****************************************************************************/

using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Messaging;
using Hyldahl.Services.TaskProcessing.Data;
using NUnit.Framework;

namespace Hyldahl.Services.TaskProcessing.Test.Data
{
    
    
    /// <summary>
    ///This is a test class for TaskSqlDataProviderTest and is intended
    ///to contain all TaskSqlDataProviderTest Unit Tests
    ///</summary>
    [TestFixture()]
    public class MessageQueueDataProviderTest
    {
        private MessageQueueDataProvider CreateTaskMessageQueueDataProvider()
        {
            MessageQueueDataProvider provider = new MessageQueueDataProvider();

            NameValueCollection settings = new NameValueCollection();
            settings.Add("connectionStringName", "TaskProcessingMSMQConnection");

            provider.Initialize("TaskProcessingMSMQConnection", settings);

            return provider;
        }

        /// <summary>
        ///A test for SaveTaskResult
        ///</summary>
        [Test()]
        [ExpectedException(typeof(ArgumentException))]
        public void SaveTaskResultNotProcessedTest()
        {
            MessageQueueDataProvider target = CreateTaskMessageQueueDataProvider();
            Task task = new Task() { IsProcessed = false };

            target.SaveTaskResult(task);
        }

        /// <summary>
        ///A test for SaveTaskResult
        ///</summary>
        [Test()]
        [ExpectedException(typeof(ArgumentException))]
        public void SaveTaskResultInvalidIdTest()
        {
            MessageQueueDataProvider target = CreateTaskMessageQueueDataProvider();
            Task task = new Task() { IsProcessed = true, Id = Guid.Empty };

            target.SaveTaskResult(task);
        }

        /// <summary>
        ///A test for SaveTaskResult
        ///</summary>
        [Test()]
        [ExpectedException(typeof(ArgumentException))]
        public void SaveTaskResultInvalidProcessingTimeTest()
        {
            MessageQueueDataProvider target = CreateTaskMessageQueueDataProvider();
            Task task = new Task() { IsProcessed = true, Id = Guid.NewGuid(), ProcessingTime = -1 };

            target.SaveTaskResult(task);
        }

        /// <summary>
        ///A test for SaveTaskResult
        ///</summary>
        [Test()]
        [ExpectedException(typeof(ArgumentException))]
        public void SaveTaskResultInvalidCompletedSuccessfullyTest()
        {
            MessageQueueDataProvider target = CreateTaskMessageQueueDataProvider();
            Task task = new Task() { IsProcessed = true, Id = Guid.NewGuid(), ProcessingTime = 1, CompletedSuccessfully = null };

            target.SaveTaskResult(task);
        }

        /// <summary>
        ///A test for SaveTaskResult
        ///</summary>
        [Test()]
        [ExpectedException(typeof(ArgumentException))]
        public void SaveTaskResultInvalidCompletedDateTest()
        {
            MessageQueueDataProvider target = CreateTaskMessageQueueDataProvider();
            Task task = new Task() { IsProcessed = true, Id = Guid.NewGuid(), ProcessingTime = 1, CompletedSuccessfully = true, CompletedDate = null };

            target.SaveTaskResult(task);
        }

        /// <summary>
        ///A test for SaveTaskResult
        ///</summary>
        [Test()]
        public void SaveTaskResultTest()
        {
            MessageQueueDataProvider target = CreateTaskMessageQueueDataProvider();
            Task task = new Task();

            task.Id                     = Guid.NewGuid();
            task.TaskType               = "TestTask";
            task.Data                   = "The Task Data";
            task.CreatedDate            = DateTime.UtcNow;

            target.CreateTask(task);

            task.IsProcessed            = true;
            task.ProcessingTime         = 1;
            task.CompletedSuccessfully  = true;
            task.CompletedDate          = DateTime.Now;
            
            target.SaveTaskResult(task);

            // TODO: Task results is not saved by the message queue data provider
            //Task compareTask = target.GetTask(task.Id);

            //Assert.IsNotNull(compareTask);
        }

        /// <summary>
        ///A test for GetUnProcessedTask
        ///</summary>
        [Test()]
        public void GetUnProcessedTaskTest()
        {
            using (MessageQueue queue = new MessageQueue(ConfigurationManager.ConnectionStrings["TaskProcessingMSMQConnection"].ConnectionString, QueueAccessMode.ReceiveAndAdmin))
            {
                queue.Purge();
            }

            MessageQueueDataProvider target = CreateTaskMessageQueueDataProvider();
            Task actual;

            // Ensure that at least one task exists
            Task firstTask = new Task();
            firstTask.Id        = Guid.NewGuid();
            firstTask.TaskType  = "TestTask";
            firstTask.Data      = "The Task Data";

            target.CreateTask(firstTask);

            Task peekTask = null;

            // Get the next task id in queue
            using (MessageQueue queue = new MessageQueue(ConfigurationManager.ConnectionStrings["TaskProcessingMSMQConnection"].ConnectionString, QueueAccessMode.Peek))
            {
                queue.Formatter = new XmlMessageFormatter(new Type[] { typeof(Task) });

                Message msg = queue.Peek();

                if (msg != null)
                    peekTask = (Task)msg.Body;
            }

            Assert.IsNotNull(peekTask);

            Assert.AreEqual(firstTask.Id, peekTask.Id);

            actual = target.GetUnProcessedTask();

            Assert.IsNotNull(actual);
            Assert.AreEqual(firstTask.Id, actual.Id);
        }

        /// <summary>
        ///A test for GetTasks
        ///</summary>
        [Test()]
        public void GetTasksTest()
        {
            MessageQueueDataProvider target = CreateTaskMessageQueueDataProvider();
            Collection<Task> actual;

            int count = 0;

            using (MessageQueue queue = new MessageQueue(ConfigurationManager.ConnectionStrings["TaskProcessingMSMQConnection"].ConnectionString, QueueAccessMode.Peek))
            {
                queue.Formatter = new XmlMessageFormatter(new Type[] { typeof(Task) });

                Message[] msgs = queue.GetAllMessages();

                count = msgs.Length;
            }

            actual = target.GetTasks();

            Assert.IsNotNull(actual);

            Assert.AreEqual(actual.Count, count);
        }

        /// <summary>
        /// A test for GetTask
        /// </summary>
        [Test()]
        public void GetTaskTest()
        {
            MessageQueueDataProvider target = CreateTaskMessageQueueDataProvider();
            Task actual;

            Task expected = new Task();

            expected.Id         = Guid.NewGuid();
            expected.TaskType   = "TestTask";
            expected.Data       = "The Task Data";

            target.CreateTask(expected);

            // TODO: Check if task has been created in message queue
            //actual = target.GetTask(expected.Id);

            //Assert.IsNotNull(actual);
        }

        /// <summary>
        ///A test for CreateTask
        ///</summary>
        [Test()]
        [ExpectedException(typeof(ArgumentNullException))]
        public void CreateTaskNullTest()
        {
            MessageQueueDataProvider target = CreateTaskMessageQueueDataProvider();
            target.CreateTask(null);
        }

        /// <summary>
        ///A test for CreateTask
        ///</summary>
        [Test()]
        [ExpectedException(typeof(ArgumentException))]
        public void CreateTaskIsProcessedTest()
        {
            MessageQueueDataProvider target = CreateTaskMessageQueueDataProvider();

            Task task = new Task();

            task.Id             = Guid.NewGuid();
            task.IsProcessed    = true;

            target.CreateTask(task);
        }

        /// <summary>
        ///A test for CreateTask
        ///</summary>
        [Test()]
        public void CreateTaskTest()
        {
            MessageQueueDataProvider target = CreateTaskMessageQueueDataProvider();
            Task task = new Task();

            task.Id         = Guid.NewGuid();
            task.TaskType   = "TestTask";
            task.Data       = "The Task Data";

            target.CreateTask(task);
        }

        /// <summary>
        ///A test for TaskSqlDataProvider Constructor
        ///</summary>
        [Test()]
        public void TaskSqlDataProviderConstructorTest()
        {
            MessageQueueDataProvider target = new MessageQueueDataProvider();
        }
    }
}
